import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  ParseIntPipe,
  Query,
  UseGuards,
  Req
} from '@nestjs/common'
import { RoleService } from './role.service'
import { BindRoleMenuDto, CreateRoleDto } from './dto/create-role.dto'
import { UpdateRoleDto } from './dto/update-role.dto'
import { MenuService } from '../menu/menu.service'
import { OperationService } from '../operation/operation.service'
import { LoggerGuard } from 'src/logger/logger.guard'
import { ResponseMsg } from 'src/common/custom.decorator'
import { EasyRequest } from 'types/global'

@Controller('auth/role')
export class RoleController {
  constructor(
    private readonly roleService: RoleService,
    private readonly menuService: MenuService,
    private readonly operationService: OperationService
  ) {}

  /**
   * @description 创建新角色
   * @param createRoleDto - 包含新角色信息的数据传输对象
   * @returns 创建的角色信息
   */
  @Post('create')
  @ResponseMsg('创建角色')
  @UseGuards(LoggerGuard)
  create(@Body() createRoleDto: CreateRoleDto, @Req() req: EasyRequest) {
    return this.roleService.create(createRoleDto, req.user?.userId)
  }

  /**
   * @description 获取所有角色
   * @returns 角色列表
   */
  @Get('list')
  findAll(
    @Query() query: { pageNum: number; pageSize: number; keyword: string },
    @Req() req: EasyRequest
  ) {
    // const { userId, roleCode } = req.user
    // 如果是管理员，就不需要传userId
    return this.roleService.findAll(query)
  }

  /**
   * @description 根据角色Id查询单个角色
   * @param id - 角色ID
   * @returns 角色信息
   */
  @Get('detail')
  findOne(@Query('id', ParseIntPipe) id: number) {
    return this.roleService.findOne(+id)
  }

  /**
   * @description 更新角色信息
   * @param id - 角色ID
   * @param updateRoleDto - 包含更新信息的数据传输对象
   * @returns 更新后的角色信息
   */
  @Patch('update')
  @ResponseMsg('更新角色')
  @UseGuards(LoggerGuard)
  update(@Body() updateRoleDto: UpdateRoleDto, @Req() req: EasyRequest) {
    return this.roleService.update(updateRoleDto, req.user)
  }

  /**
   * @description 删除角色
   * @param id - 角色ID
   * @returns 删除结果信息
   */
  @Delete('delete')
  @ResponseMsg('删除角色')
  @UseGuards(LoggerGuard)
  remove(@Query('id', ParseIntPipe) id: number, @Req() req: EasyRequest) {
    return this.roleService.remove(+id, req.user)
  }

  /**
   * @description 根据roleId查询所有menuTree以及绑定的menuId
   * @param id - 角色ID
   * @returns menuTree
   */
  @Get('menuTree')
  async findMenuTreeById(@Query('id', ParseIntPipe) id: number) {
    const [menuList, roleMenuIds] = await Promise.all([
      this.menuService.findAll(),
      this.menuService.findMenuTreeByRoleId(+id, false)
    ])

    return this.roleService.transferMenuToTree(menuList, roleMenuIds)
  }

  /**
   * @description 绑定角色的菜单id
   * @param roleId
   * @param menuIds
   * @returns
   */
  @Post('bindRoleAuthMenu')
  @ResponseMsg('分配菜单')
  @UseGuards(LoggerGuard)
  async bindRoleAuthMenu(@Body() body: { roleId: number; menuIds: number[] }) {
    const { roleId, menuIds } = body
    return this.roleService.bindRoleAuthMenu(roleId, menuIds)
  }

  /**
   * @description 绑定角色的菜单id
   * @param roleId
   * @param menuIds
   * @returns
   */
  @Post('bindRoleAuthOperation')
  @ResponseMsg('分配角色菜单下操作')
  @UseGuards(LoggerGuard)
  async bindRoleAuthOperation(
    @Body() body: { roleId: number; menuId: number; operationCodes: string[] }
  ) {
    return this.roleService.bindRoleAuthOperation(body)
  }

  /**
   * @description 绑定角色的菜单id
   * @param roleId
   * @param menuIds
   * @returns
   */
  @Post('bindRoleAuthPermission')
  @ResponseMsg('分配角色菜单下接口权限')
  @UseGuards(LoggerGuard)
  async bindRoleAuthPermission(
    @Body() body: { roleId: number; menuId: number; permissions: string[] }
  ) {
    return this.roleService.bindRoleAuthPermission(body)
  }

  /**
   * @description 绑定菜单给角色
   * @param bindRoleMenu - 包含角色ID和菜单ID的数据传输对象
   * @returns 绑定结果信息
   */
  @Post('bind')
  @ResponseMsg('分配菜单')
  @UseGuards(LoggerGuard)
  bind(@Body() bindRoleMenu: BindRoleMenuDto) {
    return this.menuService.bindRoleMenu(bindRoleMenu)
  }

  /**
   * @description 查询单个角色下的权限相关内容
   * @param params roleId 角色Id
   * @returns 权限相关内容
   */
  @Get('permission')
  async getPermission(@Query('roleId', ParseIntPipe) roleId: number) {
    return await this.menuService.findMenuTreeByRoleId(roleId)
  }
}
